
/**
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.nightonke.boommenu.Animation;

import com.nightonke.boommenu.Util;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;


import java.text.DecimalFormat;


public final class AnimatorHelp {

    private AnimatorHelp() {
    }

    private static DecimalFormat decFormat = new DecimalFormat("0.00");

    public static PropertyValuesHolder onf(String property, float... values) {

        Keyframe[] keyframes = new Keyframe[values.length];
        for (int i = 0; i < values.length; i++) {
            float pro = (float) (i + 1) / values.length;
            keyframes[i] = Keyframe.ofFloat(Float.parseFloat(decFormat.format(pro)), values[i]);
        }
        return new PropertyValuesHolder(property, keyframes);
    }

    public static AnimatorValue getPropertyAnimator(Component component, String property, Keyframe... frames) {
        return getPropertyAnimator(component, new PropertyValuesHolder(property, frames));
    }

    public static AnimatorValue getPropertyAnimator(final Component component, PropertyValuesHolder... holders) {

        AnimatorValue animatorValue = new AnimatorValue();

        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                valueUpdate(animatorValue, v, component, holders);
            }
        });
        return animatorValue;
    }

    public static void valueUpdate(AnimatorValue animatorValue, float v, final Component component, PropertyValuesHolder... holders) {
        for (PropertyValuesHolder holder : holders) {
            Keyframe[] frames = holder.getFrames();
            for (int i = 0; i < frames.length; i++) {
                float value;
                float value2;
                float progress = i == 0 ? 0 : frames[i - 1].getProgress();//动画进度
                float incremental = i == 0 ? frames[i].getProgress() : frames[i].getProgress() - frames[i - 1].getProgress();//增量

                if (v >= progress && v <= (frames[i].getProgress())) {
                    float rate = (v - progress) / incremental;//增量进度
                    value = i == 0 ? 0 : frames[i - 1].getValue();
                    value2 = frames[i].getValue();
                    switch (holder.getProperty()) {
                        case "scaleX":
                            component.setScaleX(value + (value2 - value) * rate);
                            break;
                        case "scaleY":
                            component.setScaleY(value + (value2 - value) * rate);
                            break;
                        case "alpha":
                            component.setAlpha(value + (value2 - value) * rate);
                            break;
                        case "translationX":
                            component.setTranslationX(value + (value2 - value) * rate);
                            break;
                        case "translationY":
                            component.setTranslationY(value + (value2 - value) * rate);
                            break;
                        case "rotation":
                            component.setRotation(value + (value2 - value) * rate);
                            break;
                        case "pivotX":
                            component.setPivotX(value2);
                            break;
                        case "pivotY":
                            component.setPivotY(value2);
                            break;
                        case "showProcess":
                        case "hideProcess":
                            Util.invokeProperty(component, holder.getProperty(), value2);
                            break;
                        default:
                            break;

                    }
                }
            }
        }
    }

    public static class Keyframe {
        private float progress;
        private float value;

        public Keyframe(float newProgress, float newValue) {
            this.progress = newProgress;
            this.value = newValue;
        }

        public static Keyframe ofFloat(float progress, float value) {
            return new Keyframe(progress, value);
        }

        /**
         * @params
         * @return
         * @description get the progress
        */
        public float getProgress() {
            return this.progress;
        }

        /**
         * @params
         * @return
         * @description get the value
        */
        public float getValue() {
            return this.value;
        }
    }

    public static class PropertyValuesHolder {
        private String property;
        private Keyframe[] frames;

        public PropertyValuesHolder(String newProperty, Keyframe[] newFrames) {
            this.property = newProperty;
            this.frames = newFrames.clone();
        }

        /**
         * @params
         * @return
         * @description get the property
        */
        public String getProperty() {
            return this.property;
        }

        /**
         * @params
         * @return
         * @description get the frames
        */
        public Keyframe[] getFrames() {
            return this.frames.clone();
        }
    }

}
